/** 
 * 需求：展示在页面一个 app 字段
 * 
 * 方案一：操作DOM
 * 方案二：引入vdom -> 封装函数实现复用性
 * 方案三：使用jsx
 */

// 操作DOM
// const root = document.querySelector('#root')
// const dom = document.createElement('div')
// dom.id = 'app'

// const textNode = document.createTextNode('')
// textNode.nodeValue = 'review app'
// dom.append(textNode)

// root.append(dom)

// 引入vdom -> 使用Object描述DOM 
// 操作DOM性能消耗较大【具体原理后续补充代码】
// 1. 对象化
// const textNodeEl = {
//     nodeType: 'TEXT_ELEMENT',
//     props: {
//         nodeValue: 'app',
//         children: []
//     }
// }

// const el = {
//     type: 'div',
//     props: {
//         id: 'app',
//         children: [
//             textNodeEl
//         ]
//     }
// }

// const div = document.createElement(el.type)
// div.id = el.props.id
// const textNode = document.createTextNode("")
// textNode.nodeValue = textNodeEl.props.nodeValue
// div.append(textNode)
// root.append(div)

// 封装对象
// function createElement(type, props, ...children) {
//     return {
//         type,
//         props: {
//             ...props,
//             children,
//         }
//     }
// }

function createTextNode(nodeValue) {
    return {
        type: 'TEXT_ELEMENT',
        props: {
            nodeValue,
            children: []
        }
    }
}

// const textElA = createTextNode('a_app === ')
// const textElB = createTextNode('b_app === ')
// const textElC = createTextNode('c_app === ')

// const el = createElement('div', {
//     id: 'app'
// }, textElA, textElB, textElC)

// const app = document.createElement(el.type)
// app.id = el.props.id

// const textNodeA = document.createTextNode('')
// textNodeA.nodeValue = textElA.props.nodeValue
// const textNodeB = document.createTextNode('')
// textNodeB.nodeValue = textElB.props.nodeValue
// const textNodeC = document.createTextNode('')
// textNodeC.nodeValue = textElC.props.nodeValue

// app.append(textNodeA)
// app.append(textNodeB)
// app.append(textNodeC)
// root.append(app)

// 再次抽象
// 需求： 
//   - createElement('div', { id: 'app' }, createTextNode('c_app')) 将这种方式改为
//   - createElement('div', { id: 'app' }, 'app', 'app1', 'app2', 'app3') 
function createElement(type, props, ...children) {
    return {
        type,
        props: {
            ...props,
            // 下面的child未来会补齐，其余元素
            children: children.map(child => typeof child === 'string' ? createTextNode(child) : child),
        }
    }
}


// const el = createElement('div', {
//     id: 'app'
// }, "textElA")

// console.dir(el)
// const app = document.createElement(el.type)
// app.id = el.props.id

// const textNodeA = document.createTextNode('')
// textNodeA.nodeValue = 'textElA'
// app.append(textNodeA)

// console.dir(app)
// root.append(app)

function render(el, container) {
    // 创建DOM
    const dom = el.type === "TEXT_ELEMENT" ? document.createTextNode("") : document.createElement(el.type)

    // 属性 id class 等等
    Object.keys(el.props).forEach((key) => {
        if (key !== "children") {
            dom[key] = el.props[key]
        }
    })

    const children = el.props.children
    if (children.length != 0) {
        children.forEach((child) => {
            render(child, dom)
        })
    }
   
    // 渲染DOM
    container.append(dom)
}

const App = createElement('div', { id: 'app' }, 'app_000_app')
// render(App, document.querySelector('#root'))

// 创建 ReactDOM.createRoot
// 目标需求: ReactDOM.createRoot(document.querySelector('#root')).render(App)
const ReactDOM = {
    createRoot(container) {
        return {
            render(App) {
                render(App, container)
            }
        }
    }
}

ReactDOM.createRoot(document.querySelector("#root")).render(App)